﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BLL;
using DLL;
using PagedList;
using Core;
using Logging;

namespace QuanLyBanLe
{
    public partial class FormProduct : Form
    {
        private ProducerService m_ProducerService;
        private ProductTypeService m_ProductTypeService;
        private ProductService m_ProductService;
        private UserService m_UserService;
        private IList<Producer> m_Producers;
        private IList<ProductType> m_ProductTypes;
        private IList<User> m_Users;
        private List<pGetProductByCriteria_Result> m_Products;
        private int m_PageNumber;
        private int m_PageSize;
        private int m_MaxPage;
        private int m_TotalRecord;
        private int? m_ProducerId;
        private int? m_ProductTypeId;
        private bool m_NoPrice;
        private bool m_NoWarrantyTime;
        private bool m_NoListedPrice;
        private string m_Name;
        private int? m_AddBy;
        private DateTime? m_FromDate;
        private DateTime? m_ToDate;
        private bool m_CheckInputPriceChanged;
        private int? m_PriceDiffFrom;
        private int? m_PriceDiffTo;
        private bool m_IsFiltered;
        private bool m_EnabledEvent;
        private bool m_DataChanged;
        private SortOrder m_SortOrder;
        private string m_SortColumn;
        private double m_BenefitPercent;
        private double m_DiscountPercent;

        public FormProduct()
        {
            InitializeComponent();
            m_ProducerService = new ProducerService();
            m_ProductTypeService = new ProductTypeService();
            m_ProductService = new ProductService();
            m_UserService = new UserService();
            dtgProduct.AutoGenerateColumns = false;
            m_PageNumber = 1;
            m_PageSize = 20;
            m_IsFiltered = false;
            m_EnabledEvent = false;
            m_DataChanged = false;
            m_BenefitPercent = 0;
            m_DiscountPercent = 0;
        }

        private void FormProduct_Load(object sender, EventArgs e)
        {
            lblBenefitPercent.Text = "";
            lblDiscountPercent.Text = "";
            lblTotalProductAmount.Text = "";
            BindData();
            this.Text += FormMain.GetShopInfo();
            m_DataChanged = false;
            m_EnabledEvent = true;
        }

        private void BindData()
        {
            m_Producers = m_ProducerService.GetProducers();
            m_ProductTypes = m_ProductTypeService.GetProductTypes();

            BindProducer();
            BindProductType();
            BindUsers();

            colProducer.DataSource = m_Producers;
            colProducer.ValueMember = "Id";
            colProducer.DisplayMember = "Name";

            colProductType.DataSource = m_ProductTypes;
            colProductType.ValueMember = "Id";
            colProductType.DisplayMember = "Name";

            m_Products = m_ProductService.GetProductByCriteria();
            CalculateBenefitAndDiscountPercent();
            BindProductsToGrid();
        }

        private void CalculateBenefitAndDiscountPercent()
        {
            double benefitPercent = 0;
            int i = 0;
            double discountPercent = 0;
            int j = 0;
            m_BenefitPercent = 0;
            m_DiscountPercent = 0;
            foreach (var product in m_Products)
            {
                if (product.SalePrice.HasValue && product.SalePrice.Value > 0)
                {
                    // Calculate benefit percent
                    if (product.LatestInputPrice.HasValue && product.LatestInputPrice.Value > 0)
                    {
                        benefitPercent = (product.SalePrice.Value - product.LatestInputPrice.Value) / (product.LatestInputPrice.Value * 1.0) * 100;
                        product.BenefitPercent = benefitPercent;
                        m_BenefitPercent += benefitPercent;
                        i++;
                    }
                    else
                    {
                        product.BenefitPercent = 0;
                    }

                    // Calculate discount percent
                    if (product.ListedPrice.HasValue && product.ListedPrice.Value > 0)
                    {
                        discountPercent = (product.ListedPrice.Value - product.SalePrice.Value) / (product.SalePrice.Value * 1.0) * 100;
                        product.DiscountPercent = discountPercent;
                        m_DiscountPercent += discountPercent;
                        j++;
                    }
                    else
                    {
                        product.DiscountPercent = 0;
                    }
                }
                else
                {
                    product.BenefitPercent = 0;
                    product.DiscountPercent = 0;
                }
            }
            if (i > 0)
            {
                m_BenefitPercent = m_BenefitPercent / i;
            }

            if (j > 0)
            {
                m_DiscountPercent = m_DiscountPercent / j;
            }

            lblBenefitPercent.Text = m_BenefitPercent.ToString("#.00") + "%";
            lblDiscountPercent.Text = m_DiscountPercent.ToString("#.00") + "%";
            lblTotalProductAmount.Text = m_Products.Count.ToString();
        }

        private void CalculateTotalBenefitAndDiscountPercent()
        {
            int i = 0;
            int j = 0;
            m_BenefitPercent = 0;
            m_DiscountPercent = 0;
            foreach (var product in m_Products)
            {
                if (product.SalePrice.HasValue && product.SalePrice.Value > 0)
                {
                    if (product.LatestInputPrice.HasValue && product.LatestInputPrice.Value > 0)
                    {
                        m_BenefitPercent +=  product.BenefitPercent;
                        i++;
                    }
                    if (product.ListedPrice.HasValue && product.ListedPrice.Value > 0)
                    {
                        m_DiscountPercent += product.DiscountPercent;
                        j++;
                    }
                }
            }
            if (i > 0)
            {
                m_BenefitPercent = m_BenefitPercent / i;
            }

            if (j > 0)
            {
                m_DiscountPercent = m_DiscountPercent / j;
            }

            lblBenefitPercent.Text = m_BenefitPercent.ToString("#.00") + "%";
            lblDiscountPercent.Text = m_DiscountPercent.ToString("#.00") + "%";
        }

        private void BindUsers()
        {
            m_Users = m_UserService.GetAllUsers();
            List<User> users = new List<User>();
            users.Add(new User()
            {
                Id = 0,
                Username = "Tất cả"
            });
            users.AddRange(m_Users);
            cboAddBy.DataSource = users;
        }

        private void BindProductType()
        {
            var productTypes = new List<ProductType>();
            productTypes.Add(new ProductType() { Id = 0, Name = "Tất cả" });
            productTypes.AddRange(m_ProductTypes);
            cboProductType.DataSource = productTypes;
            cboProductType.DropDownStyle = ComboBoxStyle.DropDown;
            cboProductType.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            cboProductType.AutoCompleteSource = AutoCompleteSource.ListItems;
        }

        private void BindProducer()
        {
            var producers = new List<Producer>();
            producers.Add(new Producer() { Id = 0, Name = "Tất cả" });
            producers.AddRange(m_Producers);
            cboProducer.DataSource = producers;
            cboProducer.DropDownStyle = ComboBoxStyle.DropDown;
            cboProducer.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            cboProducer.AutoCompleteSource = AutoCompleteSource.ListItems;
        }

        private void AddItemsToProductsGrid(IList<pGetProductByCriteria_Result> products)
        {
            dtgProduct.Rows.Clear();
            int i = 0;
            foreach (pGetProductByCriteria_Result product in products)
            {
                dtgProduct.Rows.Add(1);
                DataGridViewRow row = dtgProduct.Rows[i];
                row.Cells["colRowNumber"].Value = (m_PageNumber - 1) * m_PageSize + i + 1;
                row.Cells["colId"].Value = product.Id;
                row.Cells["colProductName"].Value = product.Name;
                row.Cells["colProductType"].Value = product.ProductTypeId;
                row.Cells["colProducer"].Value = product.ProducerId;
                row.Cells["colLatestInputPrice"].Value = product.LatestInputPrice;
                row.Cells["colSecondLatestInputPrice"].Value = product.SecondLatestInputPrice;
                row.Cells["colSalePrice"].Value = product.SalePrice;
                row.Cells["colBenefitPercent"].Value = product.BenefitPercent;
                row.Cells["colListedPrice"].Value = product.ListedPrice;
                row.Cells["colDiscountPercent"].Value = product.DiscountPercent;
                row.Cells["colHasWarranty"].Value = product.HasWarranty;
                row.Cells["colWarrantyTime"].Value = product.WarrantyTime;
                row.Cells["colWarningAmount"].Value = product.WarningAmount;
                row.Cells["colAmount"].Value = product.Amount;
                i++;
            }
        }

        private void BindProductsToGrid()
        {
            m_EnabledEvent = false;
            IPagedList<pGetProductByCriteria_Result> products = null;

            if (m_SortOrder == SortOrder.Ascending)
            {
                if (m_SortColumn == "colProductName")
                {
                    products = m_Products.OrderBy(x => x.Name).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colSalePrice")
                {
                    products = m_Products.OrderBy(x => x.SalePrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colListedPrice")
                {
                    products = m_Products.OrderBy(x => x.ListedPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colWarrantyTime")
                {
                    products = m_Products.OrderBy(x => x.WarrantyTime).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colWarningAmount")
                {
                    products = m_Products.OrderBy(x => x.WarningAmount).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colProductType")
                {
                    products = m_Products.OrderBy(x => x.ProductTypeName).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colProducer")
                {
                    products = m_Products.OrderBy(x => x.ProducerName).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colLatestInputPrice")
                {
                    products = m_Products.OrderBy(x => x.LatestInputPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colSecondLatestInputPrice")
                {
                    products = m_Products.OrderBy(x => x.SecondLatestInputPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colBenefitPercent")
                {
                    products = m_Products.OrderBy(x => x.BenefitPercent).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colDiscountPercent")
                {
                    products = m_Products.OrderBy(x => x.DiscountPercent).ToPagedList(m_PageNumber, m_PageSize);
                }
                else
                {
                    products = m_Products.ToPagedList(m_PageNumber, m_PageSize);
                }
            }
            else
            {
                if (m_SortColumn == "colProductName")
                {
                    products = m_Products.OrderByDescending(x => x.Name).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colSalePrice")
                {
                    products = m_Products.OrderByDescending(x => x.SalePrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colListedPrice")
                {
                    products = m_Products.OrderByDescending(x => x.ListedPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colWarrantyTime")
                {
                    products = m_Products.OrderByDescending(x => x.WarrantyTime).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colWarningAmount")
                {
                    products = m_Products.OrderByDescending(x => x.WarningAmount).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colProductType")
                {
                    products = m_Products.OrderByDescending(x => x.ProductTypeName).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colProducer")
                {
                    products = m_Products.OrderByDescending(x => x.ProducerName).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colLatestInputPrice")
                {
                    products = m_Products.OrderByDescending(x => x.LatestInputPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colSecondLatestInputPrice")
                {
                    products = m_Products.OrderByDescending(x => x.SecondLatestInputPrice).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colBenefitPercent")
                {
                    products = m_Products.OrderByDescending(x => x.BenefitPercent).ToPagedList(m_PageNumber, m_PageSize);
                }
                else if (m_SortColumn == "colDiscountPercent")
                {
                    products = m_Products.OrderByDescending(x => x.DiscountPercent).ToPagedList(m_PageNumber, m_PageSize);
                }
                else
                {
                    products = m_Products.ToPagedList(m_PageNumber, m_PageSize);
                }
            }

            AddItemsToProductsGrid(products.ToList());
            m_TotalRecord = products.TotalItemCount;
            m_MaxPage = products.PageCount;

            if (m_TotalRecord > 0)
            {
                lblTotalPage.Text = "/" + m_MaxPage.ToString();
                mnrPageIndex.Minimum = 1;
                mnrPageIndex.Enabled = true;
                mnrPageIndex.Maximum = m_MaxPage;
                mnrPageIndex.Value = m_PageNumber;
                SetEnabledForPagingNavigator();
            }
            else
            {
                m_PageNumber = 1;
                mnrPageIndex.Minimum = 0;
                mnrPageIndex.Value = 0;
                mnrPageIndex.Enabled = false;
                btnFirst.Enabled = false;
                btnPrev.Enabled = false;
                btnLast.Enabled = false;
                btnNext.Enabled = false;
                lblTotalPage.Text = string.Empty;
            }
            m_EnabledEvent = true;
        }

        private void allowText_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = false;
        }

        private void item_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                && !char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        #region DataGridEvents
        private void dtgProduct_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == dtgProduct.Columns["colDelete"].Index && e.RowIndex != -1 && !dtgProduct.CurrentRow.IsNewRow)
            {
                DialogResult dialogResult = MessageBox.Show("Bạn có muốn xóa không ?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialogResult == DialogResult.Yes)
                {
                    try
                    {
                        int amount = Convert.ToInt32(dtgProduct["colAmount", e.RowIndex].Value);
                        if (amount > 0)
                        {
                            MessageBox.Show("Sản phẩm còn hàng trong kho nên không thể xóa", "Thông báo",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                        {
                            var idColumn = dtgProduct["colId", e.RowIndex].Value;
                            if (idColumn != null)
                            {
                                int productId = Convert.ToInt32(idColumn.ToString());
                                m_ProductService.DeleteProduct(productId);
                                m_Products.RemoveAll(x => x.Id == productId);
                            }
                            dtgProduct.Rows.RemoveAt(e.RowIndex);
                            m_DataChanged = false;
                            //MessageBox.Show("Xóa thành công", "Thông báo", MessageBoxButtons.OK);
                        }
                    }
                    catch (Exception ex)
                    {
                        MyLogger.LogException("Error in FormProduct : ", ex);
                        MessageBox.Show("Có lỗi xảy ra, không xóa được sản phẩm");
                    }
                }
            }
        }

        private void dtgProduct_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (e.Control is ComboBox)
            {
                var cbo = e.Control as ComboBox;
                cbo.DropDownStyle = ComboBoxStyle.DropDown;
                cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                cbo.AutoCompleteSource = AutoCompleteSource.ListItems;
                cbo.KeyDown -= new KeyEventHandler(cbo_KeyDown);
                cbo.KeyDown += new KeyEventHandler(cbo_KeyDown);
            }

            if (dtgProduct.CurrentCell.ColumnIndex == dtgProduct.Columns["colSalePrice"].Index ||
                dtgProduct.CurrentCell.ColumnIndex == dtgProduct.Columns["colWarrantyTime"].Index ||
                dtgProduct.CurrentCell.ColumnIndex == dtgProduct.Columns["colListedPrice"].Index ||
                dtgProduct.CurrentCell.ColumnIndex == dtgProduct.Columns["colWarningAmount"].Index
                )
            {
                TextBox item = e.Control as TextBox;
                if (item != null)
                {
                    item.KeyPress += new KeyPressEventHandler(item_KeyPress);
                }
            }
            else
            {
                TextBox allowText = e.Control as TextBox;
                if (allowText != null)
                {
                    allowText.KeyPress += new KeyPressEventHandler(allowText_KeyPress);
                }
            }
        }

        private void cbo_KeyDown(object sender, KeyEventArgs e)
        {
            ComboBox cbo = sender as ComboBox;
            if (cbo.DroppedDown)
            {
                cbo.DroppedDown = false;
            }
        }

        private void dtgProduct_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (m_EnabledEvent && e.ColumnIndex != dtgProduct.Columns["colRowNumber"].Index)
            {
                m_EnabledEvent = false;
                m_DataChanged = true;

                var currentRow = dtgProduct.Rows[e.RowIndex];
                if (currentRow != null)
                {
                    if (e.ColumnIndex == currentRow.Cells["colSalePrice"].ColumnIndex)
                    {
                        int salePrice = Convert.ToInt32(currentRow.Cells["colSalePrice"].Value);                       
                        if (salePrice > 0)
                        {
                            int latestInputPrice = Convert.ToInt32(currentRow.Cells["colLatestInputPrice"].Value);
                            if (latestInputPrice > 0)
                            {
                                double benefitPercent = (salePrice - latestInputPrice) / (latestInputPrice * 1.0) * 100;
                                currentRow.Cells["colBenefitPercent"].Value = benefitPercent;
                            }
                            int listedPrice = Convert.ToInt32(currentRow.Cells["colListedPrice"].Value);
                            double discountPercent = (listedPrice - salePrice) / (salePrice * 1.0) * 100;
                            currentRow.Cells["colDiscountPercent"].Value = discountPercent;
                        }
                    }

                    if (e.ColumnIndex == currentRow.Cells["colListedPrice"].ColumnIndex)
                    {
                        int listedPrice = Convert.ToInt32(currentRow.Cells["colListedPrice"].Value);
                        if (listedPrice > 0)
                        {
                            int salePrice = Convert.ToInt32(currentRow.Cells["colSalePrice"].Value);
                            if (salePrice > 0)
                            {
                                double discountPercent = (listedPrice - salePrice) / (salePrice * 1.0) * 100;
                                currentRow.Cells["colDiscountPercent"].Value = discountPercent;
                            }
                        }
                    }
                }
                m_EnabledEvent = true;
            }
        }

        private void dtgProduct_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (m_EnabledEvent)
            {
                for (int i = 0; i < dtgProduct.Rows.Count - 1; i++)
                {
                    dtgProduct["colRowNumber", i].Value = (m_PageNumber - 1) * m_PageSize + i + 1;
                }
            }
        }


        private void dtgProduct_RowValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (dtgProduct.Rows[e.RowIndex].IsNewRow) { return; }

            if (m_EnabledEvent && m_DataChanged)
            {
                for (int i = 0; i < dtgProduct.Rows[e.RowIndex].Cells.Count; i++)
                {
                    dtgProduct.Rows[e.RowIndex].Cells[i].ErrorText = "";
                }
                AddOrUpdateProduct(e.RowIndex);
            }
        }
        #endregion DataGridEvents

        #region Paging
        private void SetEnabledForPagingNavigator()
        {
            if (m_PageNumber == m_MaxPage)
            {
                if (m_PageNumber == 1)
                {
                    btnFirst.Enabled = false;
                    btnPrev.Enabled = false;
                    btnLast.Enabled = false;
                    btnNext.Enabled = false;
                }
                else
                {
                    btnFirst.Enabled = true;
                    btnPrev.Enabled = true;
                    btnLast.Enabled = false;
                    btnNext.Enabled = false;
                }
            }
            else if (m_PageNumber == 1)
            {
                btnFirst.Enabled = false;
                btnPrev.Enabled = false;
                btnLast.Enabled = true;
                btnNext.Enabled = true;
            }
            else
            {
                btnFirst.Enabled = true;
                btnPrev.Enabled = true;
                btnLast.Enabled = true;
                btnNext.Enabled = true;
            }
        }

        private void ChangePageProduct()
        {
            m_EnabledEvent = false;
            m_DataChanged = false;

            BindProductsToGrid();
            m_EnabledEvent = true;
        }

        private void btnFirst_Click(object sender, EventArgs e)
        {
            m_PageNumber = 1;
            ChangePageProduct();
        }

        private void btnPrev_Click(object sender, EventArgs e)
        {
            m_PageNumber = m_PageNumber > 1 ? m_PageNumber - 1 : m_PageNumber;
            ChangePageProduct();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            m_PageNumber = m_PageNumber < m_MaxPage ? m_PageNumber + 1 : m_PageNumber;
            ChangePageProduct();
        }

        private void btnLast_Click(object sender, EventArgs e)
        {
            m_PageNumber = m_MaxPage;
            ChangePageProduct();
        }

        private void mnrPageIndex_ValueChanged(object sender, EventArgs e)
        {
            if (m_EnabledEvent)
            {
                m_PageNumber = Convert.ToInt32(mnrPageIndex.Value);
                ChangePageProduct();
            }
        }
        #endregion Paging

        private void btnLoc_Click(object sender, EventArgs e)
        {
            m_ProductTypeId = Convert.ToInt32(cboProductType.SelectedValue);
            if (m_ProductTypeId == 0)
            {
                m_ProductTypeId = null;
            }

            m_ProducerId = Convert.ToInt32(cboProducer.SelectedValue);
            if (m_ProducerId == 0)
            {
                m_ProducerId = null;
            }

            m_Name = txtProductName.Text.Trim();
            if (string.IsNullOrWhiteSpace(m_Name))
            {
                m_Name = null;
            }

            m_NoPrice = cbNoPrice.Checked;
            m_NoWarrantyTime = cbNoWarrantyTime.Checked;
            m_NoListedPrice = cbNoListedPrice.Checked;

            m_AddBy = Convert.ToInt32(cboAddBy.SelectedValue);
            if (m_AddBy == 0)
            {
                m_AddBy = null;
            }

            m_FromDate = null;
            if (cbFilterFromDate.Checked)
            {
                m_FromDate = dtpFromDate.Value.Date;
            }

            m_ToDate = null;
            if (cbFilterToDate.Checked)
            {
                m_ToDate = dtpToDate.Value.Date;
            }

            m_CheckInputPriceChanged = cboInputPriceChanged.Checked;

            m_PriceDiffFrom = null;
            if (!string.IsNullOrEmpty(txtPricePercentDiffFrom.Text))
            {
                m_PriceDiffFrom = Convert.ToInt32(txtPricePercentDiffFrom.Text);
            }

            m_PriceDiffTo = null;
            if (!string.IsNullOrEmpty(txtPricePercentDiffTo.Text))
            {
                m_PriceDiffTo = Convert.ToInt32(txtPricePercentDiffTo.Text);
            }

            m_PageNumber = 1;
            m_IsFiltered = true;
            m_EnabledEvent = false;
            m_Products = m_ProductService.GetProductByCriteria(m_ProductTypeId, m_ProducerId, m_Name, m_NoPrice,
                m_NoListedPrice, m_NoWarrantyTime, m_AddBy, m_FromDate, m_ToDate,
                m_CheckInputPriceChanged, m_PriceDiffFrom, m_PriceDiffTo).ToList();
            CalculateBenefitAndDiscountPercent();
            BindProductsToGrid();
            m_EnabledEvent = true;
        }

        private bool ValidateData(int rowIndex)
        {
            DataGridViewRow row = dtgProduct.Rows[rowIndex];
            bool error = true;
            // validate product name
            var data = row.Cells["colProductName"].Value;
            if (data == null || string.IsNullOrWhiteSpace(data.ToString()))
            {
                row.Cells["colProductName"].ErrorText = "Nhập tên sản phẩm";
                error = false;
            }
            else
            {
                row.Cells["colProductName"].ErrorText = "";
            }

            // validate product type
            data = row.Cells["colProductType"].Value;
            if (data == null || data.ToString() == "0")
            {
                row.Cells["colProductType"].ErrorText = "Chọn loại hàng";
                error = false;
            }
            else
            {
                row.Cells["colProductType"].ErrorText = "";
            }

            // validate producer
            data = row.Cells["colProducer"].Value;
            if (data == null || data.ToString() == "0")
            {
                row.Cells["colProducer"].ErrorText = "Chọn nhà sản xuất";
                error = false;
            }
            else
            {
                row.Cells["colProducer"].ErrorText = "";
            }

            return error;
        }

        private void AddOrUpdateProduct(int rowIndex)
        {
            bool validData = ValidateData(rowIndex);
            if (validData)
            {
                m_EnabledEvent = false;
                var cells = dtgProduct.Rows[rowIndex].Cells;
                Product product = new Product()
                {
                    Id = 0,
                    IsDeleted = false,
                    Name = cells["colProductName"].Value.ToString(),
                    ProducerId = Convert.ToInt32(cells["colProducer"].Value),
                    ProductTypeId = Convert.ToInt32(cells["colProductType"].Value),
                    AddedDate = DateTime.Now,
                    AddedBy = FormMain.s_User.Id
                };

                product.SalePrice = Convert.ToInt32(cells["colSalePrice"].Value);

                if (cells["colWarrantyTime"].Value != null)
                {
                    product.WarrantyTime = Convert.ToInt16(cells["colWarrantyTime"].Value.ToString());
                }

                if (cells["colHasWarranty"].Value != null)
                {
                    product.HasWarranty = Convert.ToBoolean(cells["colHasWarranty"].Value);
                }

                product.WarningAmount = Convert.ToInt32(cells["colWarningAmount"].Value);

                if (cells["colListedPrice"].Value != null)
                {
                    product.ListedPrice = Convert.ToInt32(cells["colListedPrice"].Value.ToString());
                }

                var idColumn = cells["colId"].Value;
                string code = "";
                try
                {
                    pGetProductByCriteria_Result productItem = new pGetProductByCriteria_Result
                    {
                        RowNumber = Convert.ToInt32(cells["colRowNumber"].Value),
                        Name = product.Name,
                        ProducerId = product.ProducerId,
                        ProductTypeId = product.ProductTypeId,                        
                        SalePrice = product.SalePrice,
                        ListedPrice = product.ListedPrice,
                        DiscountPercent = (product.SalePrice > 0 && product.ListedPrice > 0) ? (product.ListedPrice.Value - product.SalePrice.Value) / (product.SalePrice.Value * 1.0) * 100 : 0,
                        HasWarranty = product.HasWarranty,
                        WarrantyTime = product.WarrantyTime,
                        WarningAmount = product.WarningAmount
                    };

                    if (idColumn == null)
                    {
                        product.Amount = 0;
                        m_ProductService.AddProduct(product);
                        cells["colId"].Value = product.Id;
                        BarCode.CreateBarCode(product.Id.ToString(), product.Name, product.SalePrice, product.ListedPrice, ref code, FormMain.s_OS);
                        code = code.Substring(1);
                        product.Barcode = code;
                        m_ProductService.UpdateProduct(product);
                        // add new product to list of products
                        productItem.Id = product.Id;
                        productItem.Amount = 0;
                        productItem.LatestInputPrice = 0;
                        productItem.SecondLatestInputPrice = 0;
                        productItem.BenefitPercent = 0;
                        m_Products.Add(productItem);
                    }
                    else
                    {
                        product.Id = Convert.ToInt32(idColumn);
                        BarCode.CreateBarCode(product.Id.ToString(), product.Name, product.SalePrice, product.ListedPrice, ref code, FormMain.s_OS);
                        code = code.Substring(1);
                        product.Barcode = code;
                        m_ProductService.UpdateProduct(product);
                        // Update product to list of products
                        productItem.Id = product.Id;
                        productItem.Amount = Convert.ToInt32(cells["colAmount"].Value);
                        productItem.LatestInputPrice = Convert.ToInt32(cells["colLatestInputPrice"].Value);
                        productItem.SecondLatestInputPrice = Convert.ToInt32(cells["colSecondLatestInputPrice"].Value);
                        productItem.BenefitPercent = (productItem.LatestInputPrice.HasValue && productItem.LatestInputPrice.Value > 0) ? (productItem.SalePrice.Value - productItem.LatestInputPrice.Value) / (productItem.LatestInputPrice.Value * 1.0) * 100 : 0 ;
                        for(int i = 0; i < m_Products.Count; i ++)
                        {
                            if (m_Products[i].Id == productItem.Id)
                            {
                                m_Products[i] = productItem;
                                break;
                            }
                        }                        
                    }
                    // Update total total amount, total benefit percent and total discount percent
                    lblTotalProductAmount.Text = m_Products.Count.ToString();
                    CalculateTotalBenefitAndDiscountPercent();
                }
                catch (Exception ex)
                {
                    MyLogger.LogException("Error in FormProduct : ", ex);
                    MessageBox.Show("Có lỗi xảy ra, không thêm hay cập nhật được sản phẩm");
                }

                m_EnabledEvent = true;
                m_DataChanged = false;
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
            if (dtgProduct.CurrentRow != null && !dtgProduct.CurrentRow.IsNewRow)
            {
                dtgProduct.EndEdit();
                AddOrUpdateProduct(dtgProduct.CurrentRow.Index);
            }
        }

        private void cboFilterToDate_CheckedChanged(object sender, EventArgs e)
        {
            dtpToDate.Enabled = cbFilterToDate.Checked;
        }

        private void cboFilterFromDate_CheckedChanged(object sender, EventArgs e)
        {
            dtpFromDate.Enabled = cbFilterFromDate.Checked;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            if (m_IsFiltered)
            {
                cboProductType.SelectedValue = 0;
                cboProducer.SelectedValue = 0;
                txtProductName.Text = "";
                cbNoPrice.Checked = false;
                cbNoListedPrice.Checked = false;
                cbNoWarrantyTime.Checked = false;
                cboAddBy.SelectedValue = 0;
                cbFilterToDate.Checked = false;
                cbFilterFromDate.Checked = false;
                dtpFromDate.Value = DateTime.Now.Date;
                dtpToDate.Value = DateTime.Now.Date;
                cboInputPriceChanged.Checked = false;
                txtPricePercentDiffFrom.Text = "";
                txtPricePercentDiffTo.Text = "";
                m_IsFiltered = false;
                dtgProduct.Rows.Clear();
            }
        }

        private void dtgProduct_Sorted(object sender, EventArgs e)
        {
            var view = (DataGridView)sender;
            m_SortOrder = view.SortOrder;
            m_SortColumn = view.SortedColumn.Name;
            BindProductsToGrid();
        }

        private void btnFilterSalePriceIsNotGood_Click(object sender, EventArgs e)
        {
            FormProductSalePriceNotGood frm = new FormProductSalePriceNotGood();
            frm.Show();
        }
    }
}
